package com.gp.gback.system.common.util;

import com.gp.gback.system.common.exception.SOAException;
import com.gp.gback.system.common.exception.SOAExceptionCode;
import com.gp.gback.system.common.exception.SOAExceptionType;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by kongryan on 16/10/20.
 */
public class DateUtils {
    public static SimpleDateFormat normalFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static String getDateFormatString(Date date){
        return normalFormat.format(date);
    }

    public static final int SECONDS_IN_DAY = 60 * 60 * 24;

    public static final long MILLIS_IN_DAY = 1000L * SECONDS_IN_DAY;

    public static String getDateFormatString(Date date,String formatRule){
        SimpleDateFormat normalFormat = new SimpleDateFormat(formatRule);
        return normalFormat.format(date);
    }

    public static Date getStartTimeOfDate(Date date){
        Calendar day = Calendar.getInstance();
        day.setTime(date);
        day.set(Calendar.HOUR_OF_DAY, 0);
        day.set(Calendar.MINUTE,0);
        day.set(Calendar.SECOND,0);
        day.set(Calendar.MILLISECOND,0);
        return day.getTime();
    }


    public static boolean isSameDayOfDate(Date date1, Date date2) {
        long interval = date1.getTime() - date2.getTime();
        return interval < MILLIS_IN_DAY
                && interval > -1L * MILLIS_IN_DAY
                && toDay(date1.getTime()) == toDay(date2.getTime());
    }

    private static long toDay(long millis) {
        return (millis + TimeZone.getDefault().getOffset(millis)) / MILLIS_IN_DAY;
    }

    public static Date addTime(Date date, String detailTime)  {
        SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat format2 = new SimpleDateFormat("HH:mm:ss");
        SimpleDateFormat format3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String result = null;
        try {
            result = format1.format(date) + " " + format2.format(format2.parse(detailTime));
            return format3.parse(result);
        } catch (ParseException e) {
            e.printStackTrace();
            new SOAException(SOAExceptionCode.BUNIESS_EXCEPTION, SOAExceptionType.BUSINESS, "日期转换异常");
        }
        return null;
    }

    public static Date stringDateParse(String dateString) {
        try {
            Date date = normalFormat.parse(dateString);
            return date;
        } catch (ParseException e) {
            e.printStackTrace();
            new SOAException(SOAExceptionCode.BUNIESS_EXCEPTION, SOAExceptionType.BUSINESS, "日期转换异常");
        }
        return null;
    }

    public static List<String> findDateStrs(Date dBegin, Date dEnd) {
        List lDate = new ArrayList();
        lDate.add(getDateFormatString(dBegin,"yyyy-MM-dd"));
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(dEnd);
        // 测试此日期是否在指定日期之后
        while (dEnd.after(calBegin.getTime())) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            lDate.add(getDateFormatString(calBegin.getTime(),"yyyy-MM-dd"));
        }
        return lDate;
    }
    public static String getWeekOfYear(String dataStr) {
        try {
            Calendar cal = Calendar.getInstance();
            cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dataStr));
            String data = new SimpleDateFormat("yyyy-").format(cal.getTime());
            Integer i = cal.get(Calendar.WEEK_OF_YEAR);
            return data+i.toString();
        } catch (ParseException e) {
            e.printStackTrace();
            new SOAException(SOAExceptionCode.BUNIESS_EXCEPTION, SOAExceptionType.BUSINESS, "日期转换异常");
        }
        return null;
    }

    public static String getFirstAndLastOfWeek(String dataStr) {
        try {
            Calendar cal = Calendar.getInstance();

            cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dataStr));

            int d = 0;
            if (cal.get(Calendar.DAY_OF_WEEK) == 1) {
                d = -6;
            } else {
                d = 2 - cal.get(Calendar.DAY_OF_WEEK);
            }
            cal.add(Calendar.DAY_OF_WEEK, d);

            // 所在周开始日期
            String data1 = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
            cal.add(Calendar.DAY_OF_WEEK, 6);
            // 所在周结束日期
            String data2 = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
            return data1 + "-" + data2;
        } catch (ParseException e) {
            e.printStackTrace();
            new SOAException(SOAExceptionCode.BUNIESS_EXCEPTION, SOAExceptionType.BUSINESS, "日期转换异常");
        }
        return null;

    }

    public static List<String> findMonthStrs(Date dBegin, Date dEnd) {
        SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM");
        List lDate = new ArrayList();

        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(dBegin);
        calBegin.set(calBegin.get(Calendar.YEAR), calBegin.get(Calendar.MONTH), 1);

        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(dEnd);
        calEnd.set(calEnd.get(Calendar.YEAR), calEnd.get(Calendar.MONTH), 2);
        Calendar curr = calBegin;
        while (curr.before(calEnd)) {
            lDate.add(format1.format(curr.getTime()));
            curr.add(Calendar.MONTH, 1);
        }
        return lDate;
    }

    /**
     * 获取前后y周星期x的日期
     * @author fox.lin
     * @param y  x 传Calendar.MONDAY
     * @return
     */
    public static Date getWeekDay(Date date,Integer y,Integer x){

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        //n为推迟的周数，1本周，-1向前推迟一周
        cal.add(Calendar.WEEK_OF_YEAR, y);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        //想周几，这里就传几Calendar.MONDAY（TUESDAY...）
        cal.set(Calendar.DAY_OF_WEEK, x);

        return cal.getTime();
    }
}
